#include "../include/head.h"
//TLV协议
int download(int fd_socket,char *filename){
    printf("down file =%s\n",filename);
    //创建TLV协议相关结构体
    train_t node;
    //打开当前文件夹
    //int flag = -1;
    //recv(fd_socket,&flag,sizeof(int),0);
   // printf("client recv\n");
    //if(flag == 0){
      //  return -1;
   // }

    off_t filesize;
    if(recv(fd_socket,&node.length,sizeof(int),MSG_WAITALL)<=0){
        printf("接收文件长度失败\n");
        return -1;
    }
    //printf("client recv\n");
    printf("recv file length = %d\n",node.length);
    if(recv(fd_socket,node.data,node.length,MSG_WAITALL)<=0){
        printf("接收文件长度失败\n");
        return -1;
    }
    printf("client recv\n");
    printf("node.data = %s\n",node.data);

    memcpy(&filesize,node.data,sizeof(off_t));
    
    printf("开始下载文件%s，文件大小为%ld\n",filename,filesize);
    int fd=open(filename,O_RDWR|O_CREAT|O_TRUNC,0666);
    if(fd==-1){
        printf("创建文件失败\n");
        return -1;
    }
    off_t cursize = 0;
    off_t lastsize = 0;
    off_t slice = filesize/10000;
    fflush(stdout);
    while(1){
        bzero(&node,sizeof(node));
        int bytes = recv(fd_socket, &node.length, sizeof(node.length), MSG_WAITALL);
        if (bytes <= 0) {
            printf("接收数据长度失败\n");
            break;
        }
        //printf("client recv\n");
        // 长度为0表示文件传输结束
        if (node.length == 0) {
            printf("文件传输完成\n");
            break;
        }
        // 接收数据内容
        bytes = recv(fd_socket, node.data, node.length, MSG_WAITALL);
        if (bytes <= 0) {
            printf("接收文件数据失败\n");
            break;
        }
        //printf("client recv\n");
        // 写入文件
        int write_bytes = write(fd, node.data, node.length);
        if (write_bytes != node.length) {
            printf("写入文件失败\n");
            close(fd);
            return -1;
        }
        // 更新进度
        cursize += node.length;
        if (cursize - lastsize >= slice || cursize == filesize) {
            printf("下载进度: %5.2lf%%\r", 100.0 * cursize / filesize);
            fflush(stdout);
            lastsize = cursize;
        }
        // 防止无限循环
        if (cursize > filesize) {
            printf("文件大小异常\n");
            break;
        }
    }
    printf("\n下载完成: %s (%ld bytes)\n", filename, cursize);
    close(fd);
    return 0;
}
int upload(int fd_socket,char *filename){
    struct stat statbuf;
    train_t node;
    bzero(&node, sizeof(node));
    printf("filename = %s \n",filename);
    char newPath[256];  
    sprintf(newPath, "./%s", filename);

    printf("client filepath = %s\n",newPath);
    int fd = open(newPath, O_RDWR);
    if (fd == -1) {
        perror("打开文件失败\n");
        return -1;
    }
    fstat(fd,&statbuf);
    off_t filesize = statbuf.st_size;
    printf("开始上传文件: %s, 大小: %lu bytes\n", filename, filesize);
    //发送整个文件大小
    node.length = sizeof(filesize);//发个八字节
    memcpy(node.data, &filesize, sizeof(filesize));
    send(fd_socket, &node.length, sizeof(node.length), 0);//8
    send(fd_socket, node.data, node.length, 0);//二进制off_t filesize

    off_t total_sent = 0;
   // off_t slice = filesize / 100;  // 进度显示间隔
   // printf("上传进度: 0%%\r");
   // fflush(stdout);
    while (1) {
        bzero(node.data, sizeof(node.data));
        // 读取文件数据
        ssize_t sret = read(fd, node.data, sizeof(node.data));
        if (sret == 0) {
            break;  // 文件读取完毕
        }
        if (sret < 0) {
            perror("读取文件失败\n");
            close(fd);
            return -1;
        }
        // 发送数据块
        node.length = sret;
        send(fd_socket, &node.length, sizeof(node.length), 0);//发每次传多少
        send(fd_socket, node.data, node.length, 0);   //发内容
        // 更新进度
        total_sent += sret;
    //    if (total_sent % slice == 0 || total_sent == filesize) {
      //      printf("上传进度: %5.2lf%%\r", 100.0 * total_sent / filesize);
        //    fflush(stdout);
       // }
    }

    node.length = 0;
    send(fd_socket, &node.length, sizeof(node.length), 0);
    printf("\n上传完成: %s (%lu bytes)\n", filename, total_sent);
    close(fd);
    return 0;
}

int cli_upload(int fd_socket, char *filename) {
    struct stat statbuf;
    train_t node;
    bzero(&node, sizeof(node));

    char newPath[256];
    sprintf(newPath, "./%s", filename);
    printf("client filepath = %s\n", newPath);

    int fd = open(newPath, O_RDWR);
    if (fd == -1) {
        perror("打开文件失败");
        return -1;
    }

    fstat(fd, &statbuf);
    off_t filesize = statbuf.st_size;
    printf("开始上传文件: %s, 大小: %lu bytes\n", filename, filesize);

    // 发送文件总大小
    node.length = sizeof(filesize);
    memcpy(node.data, &filesize, sizeof(filesize));
    send(fd_socket, &node.length, sizeof(node.length), 0);
    send(fd_socket, node.data, node.length, 0);
    
    printf("文件总大小发送完毕\n");

    // 1. 检查服务端是否存在 .part 文件
    char exist_flag[6] = {0};
    recv(fd_socket, exist_flag, 5, MSG_WAITALL);
    printf("exist_flag == %s\n",exist_flag);

    off_t offset = 0;
    if (strcmp(exist_flag, "EXIST") == 0) {
        char choice = 0;
        printf("服务器上有未完成的文件，是否继续上传？(y/n)：");
        char c = getchar();
        getchar(); // 吸收换行
        if (c == 'y' || c == 'Y') {
            choice = 1;
        } else {
            choice = 0;
        }
        send(fd_socket, &choice, sizeof(choice), 0);
    }

    // 2. 接收服务器返回的偏移量
    recv(fd_socket, &offset, sizeof(offset), MSG_WAITALL);
    if (offset > 0) {
        printf("从断点续传，已上传 %ld bytes\n", offset);
        lseek(fd, offset, SEEK_SET); // 文件指针移动到断点
    }

    printf("下面开始上传\n");
    // 3. 开始上传
    off_t total_sent = offset;
    while (1) {
        bzero(node.data, sizeof(node.data));
        ssize_t sret = read(fd, node.data, sizeof(node.data));
        if (sret == 0) break;
        if (sret < 0) {
            perror("读取文件失败");
            close(fd);
            return -1;
        }

        node.length = sret;
        send(fd_socket, &node.length, sizeof(node.length), 0);
        send(fd_socket, node.data, node.length, 0);

        total_sent += sret;
        printf("上传进度: %5.2lf%%\r", 100.0 * total_sent / filesize);
        fflush(stdout);
    }

    node.length = 0;
    send(fd_socket, &node.length, sizeof(node.length), 0);
    printf("\n上传完成: %s (%lu bytes)\n", filename, total_sent);

    close(fd);
    return 0;
}
